<?php

const BASEDIR = __DIR__;

include BASEDIR . '/IMooc/Loader.php';

spl_autoload_register('\\IMooc\\Loader::autoload');

\App\Controller\Index::test();

# SPL标准库
// 栈：先进后出
$stack = new SplStack();
$stack->push(1);
$stack->push(2);
$stack->push(3);
echo $stack->pop(); // 3
echo $stack->pop(); // 2
echo $stack->pop(); // 1

// 队列：先进先出
$queue = new SplQueue();
$queue->enqueue(1);
$queue->enqueue(2);
$queue->enqueue(3);
echo $queue->dequeue(); // 1
echo $queue->dequeue(); // 2
echo $queue->dequeue(); // 3

// 最小堆：数值/权重/优先级等越小，通过foreach读取时，越靠前
$heap = new SplMinHeap();
$heap->insert("data2\n");
$heap->insert("data1\n");
$heap->insert("data3\n");
echo $heap->extract();  // data1
echo $heap->extract();  // data2
echo $heap->extract();  // data3

// 最大堆：与最小堆相反
$heap = new SplMaxHeap();
$heap->insert("data2\n");
$heap->insert("data1\n");
$heap->insert("data3\n");
echo $heap->extract();  // data3
echo $heap->extract();  // data2
echo $heap->extract();  // data1

// 固定长度数组
$array = new SplFixedArray(10);
$array[2] = 7;
$array[9] = 16;
var_dump($array);

// 链式操作
$db = new IMooc\Database();
// 常规
$db->where("id=1");
$db->where("name=2");
$db->order("id desc");
$db->limit(10);
// 链式
$db->where("id=1")->where("name=2")->order("id desc")->limit(10);

$obj = new IMooc\ObjectHandle();
// __get __set
$obj->title = 'hello world';
echo $obj->title;
// __call
$obj->test('hello', 123);
// __callStatic
IMooc\ObjectHandle::getFullName('hello', 'world');

// __toString
$obj = new IMooc\ObjectHandle();
echo $obj;  // 对象本身不能echo，但是通过__toString接收，便可处理不报错

// __invoke：当一个类当成方法调用时，会触发执行__invoke
echo $obj();

// 工厂模式
$db = IMooc\Factory::createDatabase();
// 单例模式
// $single = new IMooc\Singleton();    // 报错，没法直接实例化
$single1 = IMooc\Singleton::getInstance();
$single1->addAge(); // 18 -> 19
echo $single1->getAge();    // 19
$single2 = IMooc\Singleton::getInstance();
echo $single2->getAge();    // 19
$single3 = IMooc\Singleton::getInstance();
echo $single3->getAge();    // 19
// 注册树模式
// 比如在入口文件处，注册一个db1类
$init = \IMooc\Factory::createDatabase();
var_dump($init);

$db = IMooc\Register::get('db1');
var_dump($db);

// 适配器：MySQL （Tips：'mysql_connect' 已在 PHP 7.0 版本中被移除）
// $mysql = new \IMooc\Database\MySQL();
// $mysql->connect('127.0.0.1', 'root', 'root', 'test');
// $mysql->query('show databases');
// $mysql->close();
// 适配器：MySQLi
$mysqli = new \IMooc\Database\MySQLi();
$mysqli->connect('127.0.0.1', 'root', 'root', 'test');
$mysqli->query('show databases');
$mysqli->close();
// 适配器：PDO
$pdo = new \IMooc\Database\PDO();
$pdo->connect('127.0.0.1', 'root', 'root', 'test');
$pdo->query('show databases');
$pdo->close();

// 策略模式
class Page
{
    protected mixed $strategy;

    function index(): void
    {
        echo "AD:";
        $this->strategy->showAd();
        echo "<br>";

        echo "Category:";
        $this->strategy->showCategory();
        echo "<br>";
    }

    function setStrategy(\IMooc\IUserStrategy $strategy): void
    {
        $this->strategy = $strategy;
    }
}

$page = new Page;
if (isset($_GET['female'])) {
    $strategy = new \IMooc\FemaleUserStrategy;
} else {
    $strategy = new \IMooc\MaleUserStrategy;
}
$page->setStrategy($strategy);
$page->index();

// 数据对象映射模式
$user = new \App\Model\MUser(1);

var_dump($user->id, $user->name, $user->mobile, $user->regtime);

$user->mobile = '10000';
$user->name = 'test';
$user->regtime = date('Y-m-d H:i:s');
$user->serial_no = rand(10000, 99999);

class User
{
    function index()
    {
        $user = \IMooc\Factory::getUser(1);
        var_dump($user);
        $user->name = 'world';

        $this->test();

        echo "OK";
    }

    function test()
    {
        $user = \IMooc\Factory::getUser(1);
        var_dump($user);
        $user->mobile = '18955556666';
    }
}

$user = new User();
$user->index();

// 传统触发事件

class Event extends \IMooc\EventGenerator
{
    function trigger(): void
    {
        echo "Event<br/>\n";

        // update
        $this->notify();
    }
}

// 观察者1
class Observer1 implements \IMooc\Observer
{
    public function update($event_info = null): void
    {
        echo "观察者1：逻辑<br/>\n";
    }
}

// 观察者2
class Observer2 implements \IMooc\Observer
{
    public function update($event_info = null): void
    {
        echo "观察者2：逻辑<br/>\n";
    }
}

$event = new Event;
$event->addObserver(new Observer1);
$event->addObserver(new Observer2);
$event->trigger();

// 原型模式
$prototype = new \IMooc\Canvas();
$prototype->init();

$canvas1 = clone $prototype;
// 装饰器模式
$canvas1->addDecorator(new \IMooc\ColorDrawDecorator('green'));
$canvas1->addDecorator(new \IMooc\SizeDrawDecorator('18px'));

$canvas1->rect(3, 6, 4, 12);
$canvas1->draw();

echo "================================<br/>\n";
$canvas2 = clone $prototype;
$canvas2->addDecorator(new \IMooc\ColorDrawDecorator('orange'));
$canvas2->addDecorator(new \IMooc\SizeDrawDecorator('16px'));
$canvas2->rect(1, 3, 2, 6);
$canvas2->draw();

// 迭代器模式
$users = new \IMooc\AllUser();
foreach ($users as $user) {
    var_dump($user->name);
    $user->serial_no = rand(10000, 99999);
}

// 代理模式
$proxy = new \IMooc\Proxy();
$id = 1;
$proxy->getUserName($id);
$proxy->setUserName($id, 'name_upd_' . rand(1, 10));

// 自动加载配置
$config = new \IMooc\Config(__DIR__ . '/config');
var_dump($config['controller']);

IMooc\Application::getInstance(__DIR__)->dispatch();